// Kokomi.js - Three.js 组件框架
import * as kokomi from "kokomi.js";
// Three.js - 3D 渲染引擎
import * as THREE from "three";

// 世界场景组件
import World from "./World/World";

// 调试工具
import Debug from "./Debug";

// 后期处理组件
import Postprocessing from "./Postprocessing";

// 资源配置清单
import { resources } from "./resources";

// 加载动画
import LoadingAnimation from "./LoadingAnimation";

/**
 * Experience 核心控制器
 * 继承自 kokomi.Base，管理整个 3D 场景
 * 负责：场景、相机、渲染器、资源加载、后期处理等
 */
export default class Experience extends kokomi.Base {
  params; // 全局参数对象
  controls: kokomi.CameraControls; // 相机控制器
  world: World; // 世界场景
  debug: Debug; // 调试工具
  am: kokomi.AssetManager; // 资源管理器
  post: Postprocessing; // 后期处理
  loadingAnimation: LoadingAnimation | null; // 加载动画
  
  constructor(sel = "#sketch") {
    // 调用父类构造函数
    super(sel, {
      autoAdaptMobile: true, // 自动适配移动端
    });

    // 将 Experience 实例挂载到 window（方便控制台调试）
    (window as any).experience = this;

    // ==================== 全局参数配置 ====================
    this.params = {
      // 动画相关
      speed: 0, // 当前速度（0-10）
      cameraPos: {
        x: 0,
        y: 0.8,
        z: -11, // 相机初始位置
      },
      isCameraMoving: false, // 相机是否在动画中
      
      // 光照相关
      lightAlpha: 0, // 灯光透明度（0-1）
      lightIntensity: 0, // 灯光强度
      lightOpacity: 1, // 灯光不透明度
      
      // 环境相关
      envIntensity: 0, // 环境光强度
      envWeight: 0, // 环境贴图混合权重（0=夜间，1=明亮）
      
      // 反射和材质
      reflectIntensity: 0, // 地板反射强度
      floorLerpColor: 0, // 地板颜色混合比例
      carBodyEnvIntensity: 1, // 车身环境映射强度
      
      // 相机效果
      cameraShakeIntensity: 0, // 相机抖动强度
      cameraFov: 33.4, // 相机视野角度
      
      // 后期处理
      bloomLuminanceSmoothing: 1.6, // Bloom 亮度平滑度
      bloomIntensity: 1, // Bloom 强度
      
      // 特效
      speedUpOpacity: 0, // 加速特效透明度
      
      // 芙宁娜模式
      furinaLerpColor: 0, // 芙宁娜颜色混合比例
      isFurina: window.location.hash === "#furina", // 是否启用芙宁娜模式
      
      // 状态控制
      isRushing: false, // 是否正在加速
      disableInteract: false, // 是否禁用交互
    };

    // 初始化调试工具
    this.debug = new Debug();

    // 设置渲染器色调映射为 Cineon（电影风格）
    this.renderer.toneMapping = THREE.CineonToneMapping;

    // ==================== 资源加载 ====================
    // 根据是否启用芙宁娜模式过滤资源
    let resourcesToLoad = resources;
    if (!this.params.isFurina) {
      // 非芙宁娜模式，过滤掉相关资源（但保留 girl 和 girl2）
      resourcesToLoad = resourcesToLoad.filter(
        (item) => !["driving", "decal"].includes(item.name)
      );
    }
    console.log(resourcesToLoad);

    // 创建加载动画
    const loadingContainer = document.querySelector(".loading-canvas-container") as HTMLElement;
    this.loadingAnimation = new LoadingAnimation(this, loadingContainer);
    
    // 创建资源管理器
    this.am = new kokomi.AssetManager(this, resourcesToLoad, {
      useMeshoptDecoder: true, // 启用 Meshopt 解码器（压缩模型）
    });
    
    // 轮询加载进度
    let lastProgress = 0;
    const checkProgress = () => {
      if (this.loadingAnimation && this.am) {
        let progress = this.am.loadProgress || 0;
        
        // 处理 NaN 或无效值
        if (isNaN(progress) || !isFinite(progress)) {
          progress = 0;
        }
        
        // 确保进度是递增的
        progress = Math.max(lastProgress, Math.min(1, progress));
        lastProgress = progress;
        
        this.loadingAnimation.updateProgress(progress);
        
        if (progress < 1) {
          requestAnimationFrame(checkProgress);
        }
      }
    };
    
    // 立即开始检查（资源管理器构造时会自动开始加载）
    setTimeout(checkProgress, 100);

    // ==================== 相机设置 ====================
    const camera = this.camera as THREE.PerspectiveCamera;
    camera.fov = this.params.cameraFov; // 设置视野角度
    camera.updateProjectionMatrix(); // 更新投影矩阵
    
    // 设置相机初始位置
    const cameraPos = new THREE.Vector3(
      this.params.cameraPos.x,
      this.params.cameraPos.y,
      this.params.cameraPos.z
    );
    camera.position.copy(cameraPos);
    
    // 设置相机注视点（看向车的位置）
    const lookAt = new THREE.Vector3(0, 0.8, 0);
    camera.lookAt(lookAt);

    // 创建相机控制器（支持鼠标拖拽、缩放）
    const controls = new kokomi.CameraControls(this);
    controls.controls.setTarget(lookAt.x, lookAt.y, lookAt.z);
    this.controls = controls;

    // 创建世界场景
    this.world = new World(this);

    // 创建后期处理
    this.post = new Postprocessing(this);

    // 调试用：打印相机位置
    // this.update(() => {
    //   const target = new THREE.Vector3();
    //   console.log(JSON.stringify(controls.controls.getPosition(target)));
    // });

    // ==================== 每帧更新逻辑 ====================
    this.update(() => {
      if (this.params.isCameraMoving) {
        // 如果相机正在动画中，禁用手动控制
        this.controls.controls.enabled = false;
        // 将相机设置到目标位置（由 GSAP 动画控制）
        this.controls.controls.setPosition(
          this.params.cameraPos.x,
          this.params.cameraPos.y,
          this.params.cameraPos.z
        );
      } else {
        // 动画结束后，恢复手动控制
        this.controls.controls.enabled = true;
      }
    });
  }
}
